package controller;

import javax.swing.*;
import java.awt.*;
import java.util.*;
import javax.swing.Timer;

import model.*;

@SuppressWarnings("serial")
class AnimationWindow extends JPanel implements Observer {

	private AnimationEventListener eventListener; //
	private Timer timer;
	private boolean mode;
	private Ball ball;
	private Board board;

	public AnimationWindow(Ball ball, Board board) {
		super();
		this.ball = ball;
		this.board = board; 
		int L = board.getL();

		// Make View a dependent of Model
		ball.addObserver(this);
		board.addObserver(this);

		// Create Controller (AnimationEventListener)
		// The setMode method sets up the AnimationEventListener to 
		// also catch all mouse events on the View
		eventListener = new AnimationEventListener(ball, board);

		// this only initializes the timer, we actually start and stop the
		// timer in the setMode() method

		// The first parameter is how often (in milliseconds) the timer
		// should call us back.  50 milliseconds = 20 frames/second
		timer = new Timer(55, eventListener);
		mode = false;
		setPreferredSize(new Dimension(20*L, 20*L));
		setBackground(new Color(0x000000));
	}

	// This is just here so that we can accept the keyboard focus
	public boolean isFocusable() {
		return true;
	}
	
	public void paint(Graphics g) {
		// modifies: <g>
		// effects: Repaints the Graphics area <g>.  Swing will then send the
		//          newly painted g to the screen.
		int L = board.getL();
		
		super.paint(g);
		
		ball.paintShape(g);
		
		for (IGizmo each : board.getGizmos())
			each.paintShape(g);

		if (!mode) {
			g.setColor(new Color(0x555555));
			for (int i=1 ; i<20 ; i++) {
				g.drawLine(i*L, 0, i*L, 20*L);
				g.drawLine(0, i*L, 20*L, i*L);
			}
		}

	}// end of paint()

	
	public void setMode(boolean m) {
		// modifies: this
		// effects: changes the mode to <m>.

		if (mode) {
			// we're about to change mode: turn off all the old listeners
			removeMouseListener(eventListener);
			removeMouseMotionListener(eventListener);
			removeKeyListener(eventListener);
		}

		mode = m;

		if (mode) {
			// the mode is true: turn on the listeners
			addMouseListener(eventListener);
			addMouseMotionListener(eventListener);
			addKeyListener(eventListener);
			requestFocus();           // make sure keyboard is directed to us
			timer.start();
		}
		else {
			timer.stop();
		}
		
		repaint();
	}// end of setMode()
	

	public void update(Observable o, Object arg) {

		// Observable Model passes a rectangle of damaged area
		// to be updated during painting	
		Rectangle repaintArea = (Rectangle) arg;

		// Have Swing tell the AnimationWindow to run its paint()
		// method.  One could also call repaint(), but this would
		// repaint the entire window as opposed to only the portion that
		// has changed.

		this.repaint();

		//repaint(repaintArea.x, repaintArea.y, repaintArea.width, repaintArea.height);
	}// end of update()
	
	
}// end of class

